﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GrayParrot.Web.Formly
{
    public class FormlyFactory : IFormlyFactory
    {
        private List<FieldItem> m_fields = null;

        public FormlyFactory()
        {
            m_fields = new List<FieldItem>();
        }

        public List<FieldItem> Create()
        {
            return m_fields;
        }

        public IFormlyFactory AddEvent(EventTypes eventType, string callback)
        {
            if (m_fields.Count() > 0)
            {
                FieldItem m_item = m_fields[m_fields.Count() - 1];

                string f = null;
                object m_func = null;

                f = string.Format(@"function(options, scope){{ {0}(options, scope); }}", callback);
                m_func = new Newtonsoft.Json.Linq.JRaw(f);

                m_item.TemplateOptions.Events.Add(new EventCallback() { Evento = eventType, Callback = f });
            }

            return this;
        }

        public IFormlyFactory AddAddOn(Position position, string className, string text=null, string onClick=null)
        {
            if (m_fields.Count() > 0)
            {
                FieldItem m_item = m_fields[m_fields.Count()-1];

                string f = null;
                object m_func = null;

                if ((onClick != null) && (onClick != string.Empty))
                {
                    f = string.Format(@"function(options, scope){{ {0}(options, scope); }}", onClick);
                    m_func = new Newtonsoft.Json.Linq.JRaw(f);
                }
                else
                {
                    if (onClick == string.Empty)
                    {
                        f = string.Format(@"{0}", onClick);
                        m_func = new Newtonsoft.Json.Linq.JRaw(f);
                    }
                }

                switch (position)
                {
                    case Position.Left:
                        m_item.TemplateOptions.AddonLeft = new AddOn()
                        {
                            Class = className,
                            Text = text,
                            OnClick = (string.IsNullOrWhiteSpace(f) ? f : m_func.ToString())
                        };
                        break;
                    case Position.Right:
                        m_item.TemplateOptions.AddonRight = new AddOn()
                        {
                            Class = className,
                            Text = text,
                            OnClick = (string.IsNullOrWhiteSpace(f) ? f : m_func.ToString())
                        };
                        break;
                    default:
                        break;
                }
            }

            return this;
        }

        public IFormlyFactory AddDateTimePicker(string key,
                                        string label, string description, string placeHolder,
                                        bool disabled, bool required,
                                        DataDatetimepickerConfig datetimepickerConfig = null, DateTime? value = null)
        {
            m_fields.Add(new FieldItem()
            {
                Key = key,
                Type = FormFieldTypes.DateTimepicker,
                TemplateOptions = InternalHelper.CreateDateTimePicker(label, description, placeHolder, disabled, required, datetimepickerConfig, value)
            });

            return this;
        }

        public IFormlyFactory AddMaskedInput(string key,
                                string label, string description, string placeHolder,
                                bool disabled, bool required,
                                string mask = null)
        {
            m_fields.Add(new FieldItem()
            {
                Key = key,
                Type = FormFieldTypes.MaskedInput,
                TemplateOptions = InternalHelper.CreateMaskedInput(label, description, placeHolder, disabled, required, mask)
            });

            return this;
        }

        public IFormlyFactory AddTimePicker(string key,
                        string label, string description, string placeHolder,
                        bool disabled, bool required)
        {
            m_fields.Add(new FieldItem()
            {
                Key = key,
                Type = FormFieldTypes.Timepicker,
                TemplateOptions = InternalHelper.CreateTimepicker(label, description, placeHolder, disabled, required)
            });

            return this;
        }

        public IFormlyFactory AddDatePicker(string key,
                        string label, string description, string placeHolder,
                        bool disabled, bool required,
                        string datepickePopup = null, DateTime? value = null)
        {
            m_fields.Add(new FieldItem()
            {
                Key = key,
                Type = FormFieldTypes.Datepicker,
                TemplateOptions = InternalHelper.CreateDatepicker(label, description, placeHolder, disabled, required, datepickePopup, value)
            });

            return this;
        }

        public IFormlyFactory AddRepeatSection(string key,
                string label, string description, string placeHolder,
                bool disabled, bool required, DrawDirections drawDirection)
        {
            m_fields.Add(new FieldItem()
            {
                Key = key,
                Type = FormFieldTypes.RepeatSection,
                TemplateOptions = InternalHelper.CreateRepeatSection(label, description, placeHolder, disabled, required, drawDirection)
            });

            return this;
        }

        public IFormlyFactory AddInput(string key,
                string label, string description, string placeHolder,
                bool disabled, bool required, int? minLength = null, int? maxLength = null, TextFieldBehaviors behavior = TextFieldBehaviors.Text)
        {
            m_fields.Add(new FieldItem()
            {
                Key = key,
                Type = FormFieldTypes.Input,
                TemplateOptions = InternalHelper.CreateInput(label, description, placeHolder, disabled, required, minLength, maxLength, behavior)
            });

            return this;
        }

        public IFormlyFactory AddNumber(string key,
                string label, string description, string placeHolder,
                bool disabled, bool required, int? minLength = null, int? maxLength = null, int? min = null, int? max = null, double? value = null)
        {
            m_fields.Add(new FieldItem()
            {
                Key = key,
                Type = FormFieldTypes.Number,
                TemplateOptions = InternalHelper.CreateNumber(label, description, placeHolder, disabled, required, minLength, maxLength, min, max, value)
            });

            return this;
        }

        public IFormlyFactory AddTextArea(string key,
                string label, string description, string placeHolder,
                bool disabled, bool required, short rows = 0, short cols = 0)
        {
            m_fields.Add(new FieldItem()
            {
                Key = key,
                Type = FormFieldTypes.Textarea,
                TemplateOptions = InternalHelper.CreateTextArea(label, description, placeHolder, disabled, required, rows, cols)
            });

            return this;
        }

        public IFormlyFactory AddDecimal(string key,
        string label, string description, string placeHolder,
        bool disabled, bool required, int? minLength = null, int? maxLength = null, int? min = null, int? max = null, double? value = null, double? step = null)
        {
            m_fields.Add(new FieldItem()
            {
                Key = key,
                Type = FormFieldTypes.Number,
                TemplateOptions = InternalHelper.CreateDecimal(label, description, placeHolder, disabled, required, minLength, maxLength, min, max, value, step)
            });

            return this;
        }

        public IFormlyFactory AddCheckBox(string key, string label, bool disabled, bool required, bool isChecked)
        {
            m_fields.Add(new FieldItem()
            {
                Key = key,
                Type = FormFieldTypes.Checkbox,
                TemplateOptions = InternalHelper.CreateCheckBox(label, disabled, required, isChecked)
            });

            return this;
        }

        public IFormlyFactory AddMultiCheckBox(string key,
                string label, string description, string placeHolder,
                bool disabled, bool required, string callback = null, string labelProp = null, string valueProp = null, string dependsBy = null, bool forceLoad = false)
        {
            m_fields.Add(new FieldItem()
            {
                Key = key,
                Type = FormFieldTypes.MultiCheckbox,
                TemplateOptions = InternalHelper.CreateMultiCheckBox(label, description, placeHolder, disabled, required, callback, labelProp, valueProp, dependsBy, forceLoad)
            });

            return this;
        }

        public IFormlyFactory AddRadio(string key,
            string label, string description, string placeHolder,
            bool disabled, bool required, string callback = null, string defaultValue = null)
        {
            m_fields.Add(new FieldItem()
            {
                Key = key,
                Type = FormFieldTypes.Radio,
                TemplateOptions = InternalHelper.CreateRadio(label, description, placeHolder, disabled, required, callback)
            });

            return this;
        }

        public IFormlyFactory AddSelect(string key,
            string label, string description, string placeHolder,
            bool disabled, bool required, string groupProp = null, string callback = null, string labelProp = null, string valueProp = null, string dependsBy = null, bool forceLoad = false)
        {
            m_fields.Add(new FieldItem()
            {
                Key = key,
                Type = FormFieldTypes.Select,
                TemplateOptions = InternalHelper.CreateSelect(label, description, placeHolder, disabled, required, groupProp, callback, labelProp, valueProp, dependsBy, forceLoad)
            });

            return this;
        }

        public IFormlyFactory AddUISelect2(string key,
               string label, string description, string placeHolder,
               bool disabled, bool required, string groupProp = null, string callback = null, 
               string labelProp = null, string valueProp = null, string dependsBy = null, bool forceLoad = false, 
               uint? minimumInputLength = null, string editProp = null)
        {
            m_fields.Add(new FieldItem()
            {
                Key = key,
                Type = FormFieldTypes.UISelect2,
                TemplateOptions = InternalHelper.CreateUISelect2(label, description, placeHolder, disabled, required, groupProp, callback, labelProp, valueProp, dependsBy, forceLoad, 
                                                                 minimumInputLength, editProp)
            });

            return this;
        }

        public IFormlyFactory AddImage(string key, string label, string description, string placeHolder, bool disabled, bool required, string folder)
        {
            m_fields.Add(new FieldItem()
            {
                Key = key,
                Type = FormFieldTypes.Input,
                TemplateOptions = InternalHelper.CreateImage(label, description, placeHolder, disabled, required, folder)
            });

            return this;
        }
    }
}
